/**
  ETFAna project, Anyang Normal University && IMP-CAS
  \class ETFPID
  \brief class for particle identification in RIB exps. This class takes tracks
  on both sides of the dipole magnet to extract particle A/Z, and particle velocity
  beta.
  \author SUN Yazhou, asia.rabbit@163.com
  \since 2021-11-10
  \date 2023-06-02 last modified
  \attention
  changelog
  <table>
  <tr>  <th>Date         <th>Author      <th>Description                   </tr>
  <tr>  <td>2023-06-02   <td>Asia Sun    <td>ETFVPID inheritence added     </tr>
  </table>

  \copyright Copyright (c) 2021-2024 Anyang Normal U. && IMP-CAS with LGPLv3 LICENSE
*/

#ifndef ETFPID_h
#define ETFPID_h

#include "ETFVPID.h"

class ETFPID : public ETFVPID{
public:
  ETFPID();
  virtual ~ETFPID();

  virtual void Initialize() override;
  virtual void Register() override; ///< register to the main tree
  virtual void Configure() override;

  /// propogate the particle in the dipole magnet to meet the tracks given by the DCs
  /// currently and usually a uniform magnetic field is assumed, as it is both
  /// appropriate and efficient
  /// \param tof2: from the target to TOFWall
  /// \param pIn[0-1]: {k, b} from postTaTrk
  /// \param pOut[0-1]: {k, b} from postMagTrk
  virtual bool Fly(const double *pIn, const double *pOut, double tof2) override;
  /// the same fly, but collecting information using singleton classes in ETFAna
  /// \param istof: whether we only call fly to calculate the tofs
  virtual bool Fly(bool istof = false) override;

  ///@{ incident particle identification
  double tof1() const{ return ftof1; } ///< time-of-flight from Tstart to Tstop
  void SetTOF1(double tof1){ ftof1 = tof1; }
  void SetTOF2(double tof2){ ftof2 = tof2; }
  double GetBeta0() const{ return fBeta0; }
  double beta0() const{ return fBeta0; }
  double gamma0() const{ return fGamma0; }
  double bg0() const{ return fBG0; } // beta0*gamma0
  ///@}


  ///@{ fragment identification
  double tof2() const{ return ftof2; } ///< time-of-flight from Tstop to TOFWall
  double GetBeta() const{ return fBeta; }
  double beta() const{ return fBeta; }
  double gamma() const{ return fGamma; }
  double bg() const{ return fBG; } /// beta*gamma
  double trkLenT() const{ return fTrkLenT; }
  double GetAoZ() const{ return fAoZ; }
  double aoz() const{ return fAoZ; }
  double poz1() const; /// for calibration purposes
  double beta1() const; /// for calibration purposes
  double bg1() const; /// for calibration purposes
  double aoz1() const; /// for calibration purposes
  double GetPoZ() const{ return fPoZ; }
  double poz() const{ return fPoZ; }
  double GetBrho() const{ return fBrho; }
  double brho() const{ return fBrho; }
  double rho() const{ return fRho; }
  ///@}

  ///@{ calculate parallel momentum and its relevant uncertainties
  /// \brief calculate the parallel momentum of the heavy residue (the core)
  /// and store the results in the relevant member varibles
  /// \retval false: not eligible for calculating pozpl
  bool ParallelMomentum();
  double cospl() const{ return fCospl; }
  double dcospl() const{ return fdCospl; }
  double pozpl() const{ return fPoZpl; }
  double dpozpl() const{ return fdPoZpl; }
  double BGC() const{ return fBGC; }
  double dBGC() const{ return fdBGC; }
  ///@}

  /// \return the differences of mag-exiting x-s calculated from postmagtrk and the mag-arc
  double dx2() const; // x2arr[0] - x2arr[1]

  virtual void ConstructGraph() override; ///< update fCurve
  virtual void Print() override;

  void SetCalculateParallelMomentum(bool opt){ fIsParaMom = opt; }

  ClassDefOverride(ETFPID, 1); ///< particle identification

protected:
  ///@{ variables for incident-particle identification
  double ftof1; ///< time-of-flight from Tstart to Tstop
  double fBeta0, fGamma0, fBG0; ///< beta0: for incident particles
  ///@}

  double fAoZ;
  double fPoZ, fBrho;
  double fZO, fXO; ///< (zo,xo): center of the circle overlapping the arc
  double fTrkLenT; ///< total track length corresponding to tof2
  double ftof2; ///< time of flight from tstop to tofw
  double fRho; ///< radius of the circle overlapping the arc
  double fBeta, fGamma, fBG; ///< beta, gamma, beta*gamma

  ///@{ parallel momentum and its relevant uncertainties
  /// cos<n0,n1> (vec. of inci. v.s. exit) & err & parallel poz component
  double fCospl, fdCospl, fPoZpl, fdPoZpl;
  double fBGC, fdBGC; ///< beta*gamma*u*cospl & err, pozpl = BGC*aoz
  ///@}

  /// x2: abscissa of Mag exit point from real trk and calculated arc
  /// as a PID estimator; 0-1: real-calcu
  double fX2Arr[2];

  bool fIsParaMom; // whether calculate parallel momentum
};

#endif
